package com.mlnx.data.dao.iml;

import com.mlnx.common.form.PageForm;
import com.mlnx.common.utils.MyLog;
import com.mlnx.data.dao.SpoStore;
import com.mlnx.data.entity.SpoInfo;
import com.mlnx.data.pojo.form.SpoInfoForm;
import com.mlnx.data.pojo.vo.SpoInfoVo;
import com.mlnx.device.util.SortUtil;
import com.mlnx.service.base.properties.MutilDeviceProperties;
import org.shan.spring.mongodb.MongodbUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;

import javax.annotation.PostConstruct;
import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zzb
 * @create 2019/10/28 8:58
 */
@Repository("spoMonggoDb")
public class SpoMonggoDb implements SpoStore {

    private MyLog log = MyLog.getLog(SpoMonggoDb.class);

    @Autowired
    private MutilDeviceProperties mutilDeviceProperties;

    @Override
    public void save(SpoInfo spoInfo) {
        MongodbUtils.save(spoInfo, mutilDeviceProperties.getStore().getSpoCollectionName());
    }

    @PostConstruct
    @Override
    public void init() {

        log.info("开始初始化spo mongodb存储");

        try {
            Map<String, Sort.Direction> map = new HashMap<>();
            map.put("patientId", Sort.Direction.ASC);
            map.put("time", Sort.Direction.ASC);
            MongodbUtils.setIndex(mutilDeviceProperties.getStore().getSpoCollectionName(), map, true);
        } catch (Exception e) {
            log.error(e, "设置血氧索引失败，失败已经捕捉不影响使用");
        }

        log.info("初始化spo mongodb存储结束");
    }


    @Override
    public List<SpoInfo> getSpos(Integer patientId, Long startTime, Long endTime) {
        Criteria criteria = Criteria.where("patientId").is(patientId);
        criteria.and("time").gt(startTime).lt(endTime);
        Query query = Query.query(criteria);
        query.with(new Sort(Sort.Direction.ASC, "time"));

        List<SpoInfo> spoInfos = MongodbUtils.find(SpoInfo.class, query, mutilDeviceProperties.getStore().getSpoCollectionName());

        return spoInfos;
    }


    @Override
    public void updateSpo(SpoInfo spoInfo) {
        Criteria criteria = Criteria.where("patientId").is(spoInfo.getPatientId());
        criteria.and("time").is(spoInfo.getTime());

        try {
            MongodbUtils.updateFirst(spoInfo, criteria, mutilDeviceProperties.getStore().getSpoCollectionName());
        } catch (IntrospectionException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void deleteSbp(SpoInfo spoInfo) {
        Criteria criteria = Criteria.where("patientId").is(spoInfo.getPatientId());
        criteria.and("time").is(spoInfo.getTime());

        Query query = Query.query(criteria);

        MongodbUtils.remove(query, mutilDeviceProperties.getStore().getSpoCollectionName());
    }

    @Override
    public SpoInfoVo getPageSpos(PageForm pageForm, SpoInfoForm spoInfoForm) {
        Criteria criteria = new Criteria();
        if (spoInfoForm != null) {
            if (spoInfoForm.getDeviceId() != null) {
                criteria.and("deviceId").is(spoInfoForm.getDeviceId());
            }
            if (spoInfoForm.getPatientId() != null) {
                criteria.and("patientId").is(spoInfoForm.getPatientId());
            }
            if (spoInfoForm.getStartTime() != null) {
                criteria.and("time").gt(spoInfoForm.getStartTime()).lt(spoInfoForm.getEndTime());
            }

        }

        Query query = Query.query(criteria);
        query.skip((pageForm.getCurrent() - 1) * pageForm.getSize());
        query.limit(Math.toIntExact(pageForm.getSize()));
        if (spoInfoForm != null) {
            if (spoInfoForm.getSorter() != null && !"{}".equals(spoInfoForm.getSorter())) {
                Map<String, String> map = SortUtil.parseSorter(spoInfoForm.getSorter());

                for (String str : map.keySet()) {
                    query.with(new Sort(Sort.Direction.valueOf(map.get(str)), str));
                }
            }
        }
        List<SpoInfo> spoInfos = MongodbUtils.find(SpoInfo.class, query, mutilDeviceProperties.getStore().getSpoCollectionName());
        Integer total = Math.toIntExact(MongodbUtils.count(new Query(criteria), mutilDeviceProperties.getStore().getSpoCollectionName()));
        SpoInfoVo spoInfoVo = new SpoInfoVo();
        spoInfoVo.setRecords(spoInfos);
        spoInfoVo.setTotal(total);
        spoInfoVo.setSize(Math.toIntExact(pageForm.getSize()));
        spoInfoVo.setCurrent(Math.toIntExact(pageForm.getCurrent()));
        return spoInfoVo;
    }
}
